package com.specter.sure.core;

import java.io.Serial;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

/**
 * Note:安全上下文
 * 
 * @author Liang.Wang
 * @version 2010-11-25
 */
public class AuthContext implements Serializable {
	@Serial
	private static final long serialVersionUID = -6157336207280713429L;

	public static final String KEY_REQUESTS = "com.specter.sure.core.AuthContext.Request";
	public static final String KEY_RESPONSE = "com.specter.sure.core.AuthContext.Response";
	public static final String KEY_USERINFO = "com.specter.sure.core.AuthContext.Authorized";

	private static ThreadLocal<AuthContext> contextHolder = new InheritableThreadLocal<AuthContext>() {
		@Override
		protected synchronized AuthContext initialValue() {
			return new AuthContext();
		}
	};

	private transient Map<String, Object> data;

	public AuthContext() {
		this.data = new HashMap<>();
	}

	public static void remove() {
		contextHolder.remove();
	}

	public static void init(HttpServletRequest req, HttpServletResponse res) {
		put(KEY_REQUESTS, req);
		put(KEY_RESPONSE, res);
	}

	public static <T> T get(Class<T> clazz, String key) {
		AuthContext context = contextHolder.get();
		Map<String, Object> data = context.data;
		return clazz.cast(data.get(key));
	}

	public static void put(String key, Object value) {
		AuthContext context = contextHolder.get();
		Map<String, Object> data = context.data;
		data.put(key, value);
	}

	public static HttpServletRequest getRequest() {
		return get(HttpServletRequest.class, KEY_REQUESTS);
	}

	public static HttpServletResponse getResponse() {
		return get(HttpServletResponse.class, KEY_RESPONSE);
	}

	public static HttpSession getSession() {
		return getRequest().getSession();
	}

	public static ServletContext getServletContext() {
		return getSession().getServletContext();
	}

	public static void setUserDetail(Authorized userDetail) {
		put(KEY_USERINFO, userDetail);
	}

	public static Authorized getUserDetail() {
		return get(Authorized.class, KEY_USERINFO);
	}

}
